﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Web.Security;
using System.Diagnostics;

namespace ERPStudio
{
    public partial class LoginAppFrm : FrmCard
    {
        private Guid _UserID = Guid.Empty;
        public Guid AutentifiedUserID
        {
            get { return _UserID; }
        }
        private String _UserName = String.Empty;
        public String AutentifiedUserName
        {
            get { return _UserName; }
        }
        public List<eInfoModule> lstModule = null;
        public LoginAppFrm(List<eInfoModule> _lst) : base(null)
        {
            lstModule = _lst;
            InitializeComponent();
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration("ERPStudio.exe");
            KeyValueConfigurationCollection configSettings = config.AppSettings.Settings;
            while (configSettings["LastUser"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("LastUser", ""));
                config.Save();
            }
            LastUser = configSettings["LastUser"].Value.ToString();
            while (configSettings["Autentificare"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("Autentificare", "False"));
                config.Save();
            }
            retineCB.Checked = Convert.ToBoolean(configSettings["Autentificare"].Value);
            while (configSettings["LastPassword"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("LastPassword", ""));
                config.Save();
            }
            LastPassword = configSettings["LastPassword"].Value.ToString();
            statusStrip1.SizingGrip = false;

        }

        private String LastPassword = String.Empty;
        private String LastUser = String.Empty;

        private void LoginAppFrm_Load(object sender, EventArgs e)
        {
            AddButton("Autentificare", global::ERPStudio.Properties.Resources.home, Autentificare, ToolStripItemAlignment.Right, true);
            AddButton("Setari Baza Date", global::ERPStudio.Properties.Resources.shield, SetariDB, ToolStripItemAlignment.Left, false);
            ActiveControl = userTB;
            userTB.Text = LastUser;
            if (userTB.Text != String.Empty)
                ActiveControl = passwordTB;
            HandleSalvare += Autentificare;
        }

        private void SetariDB(object sender, EventArgs e)
        {
            FrmLogin f = new FrmLogin(true, lstModule);
            f.ShowDialog();
        }

        int incercari = 0;
        /// <summary>
        /// Autentifica cu utilizatorul si parola salvate anterior
        /// </summary>
        /// <returns></returns>
        public Boolean Autentifica()
        {
            MyTrace("o-->Autentifica()");
            SqlDataReader ret = null;
            String parolaDB = String.Empty, salt = String.Empty;
            SqlCommand cmd = null;
            MembershipUser muser = null;
            try
            {
                _UserName = LastUser.Trim();
                MembershipUserCollection mucret = Membership.FindUsersByName(_UserName);
                if (mucret == null || mucret.Count == 0)
                {
                    _UserID = Guid.Empty;
                    MyTrace("<--oAutentifica(1)");
                    return false;
                }
                muser = mucret[_UserName];
                _UserID = (Guid)muser.ProviderUserKey;

            }
            catch (Exception)
            {
                _UserID = Guid.Empty;
                MyTrace("<--oAutentifica(2)");
                return false;
            }
            finally
            {
                if (ret != null)
                    ret.Close();
                if (cmd!=null)
                    InchideConexiune(cmd.Connection);
            }

            String lostPass = Decrypt(LastPassword, "gfdgfdrrttrd6786vjbnvbc");

            if (!Membership.ValidateUser(_UserName, lostPass))
            {
                _UserID = Guid.Empty;
                incercari++;
                if (incercari == 3 && _UserName.ToLower() == "admin")
                {
                    if (muser == null)
                    {
                        MyTrace("<--oAutentifica(3)");
                        return false;
                    }

                    String Parola = muser.ResetPassword();
                    muser.ChangePassword(Parola, passwordTB.Text);
                    Membership.UpdateUser(muser);
                }
                MyTrace("<--oAutentifica(4)");
                return false;
            }
            MyTrace("<--oAutentifica(5)");
            return true;            
        }
        
        private void Autentificare(object sender, EventArgs e)
        {
            MyTrace("o-->Autentificare()");
            if (userTB.Text.Trim() == String.Empty)
            {
                MessageBox.Show("Va rugam sa introduceti numele utilizatorului",
                       "Stop",
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Stop);
                ActiveControl = userTB;
                MyTrace("<--oAutentificare(0)");
                return;
            }
            //securitatea system
            
            SqlDataReader ret=null;
            String parolaDB = String.Empty, salt = String.Empty;
            SqlCommand cmd = null;
            SqlConnection conn = DeschideConexiune("AdminConnectionString");
            MembershipUser muser = null;
            if(conn==null)
            {
                Application.Exit();
                MyTrace("<--oAutentificare(1)");
                return;
            }

            try
            {
                _UserName = userTB.Text.Trim();
                MyTrace("Membership.FindUsersByName(" + _UserName.ToString() + ") - provider:" + Membership.Provider.Name);

                
                MembershipUserCollection mucret = Membership.FindUsersByName(_UserName);
                if (mucret == null || mucret.Count == 0)
                {
                    MessageBox.Show("Utilizator necunoscut!",
                           "Stop",
                           MessageBoxButtons.OK,
                           MessageBoxIcon.Stop);
                    ActiveControl = userTB;
                    MyTrace("<--oAutentificare(2)");
                    return;
                }
                muser = mucret[_UserName];
                if (!muser.IsApproved && _UserName.ToLower()=="admin")
                {
                    muser.IsApproved = true;
                    muser.UnlockUser();
                    Membership.UpdateUser(muser);
                }
                _UserID = (Guid)muser.ProviderUserKey;
            }
            catch(Exception ex)
            {
                  _UserID = Guid.Empty;
                   MessageBox.Show("Va rugam sa reporniti aplicatia! - Eroare la incarcarea configurarilor!",
                       "Stop",
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Stop);
                   MyTrace("<--oAutentificare(3)" + ex.ToString());
                   return;
            }
            finally
            {
                if(ret!=null)
                    ret.Close();
                if(cmd!=null)
                    InchideConexiune(cmd.Connection);
            }
            if(!Membership.ValidateUser(_UserName,passwordTB.Text))
            {
                _UserID = Guid.Empty;
                MessageBox.Show("Eorare autentificare!",
                       "Stop",
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Stop);
                ActiveControl = userTB;
                 _UserID = Guid.Empty;
                incercari++;
                if (incercari == 3 && _UserName.ToLower() == "admin")
                {
                    if (muser == null)
                    {
                        MyTrace("<--oAutentificare(4)");
                        return;
                    }
                    String Parola = String.Empty;
                    try
                    {
                        Parola = muser.ResetPassword();
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Contains("The user account has been locked out."))
                        {
                            muser.UnlockUser();
                            Membership.UpdateUser(muser);
                            Parola = muser.ResetPassword();
                        }
                        else
                            TrateazaExceptie(ex);
                    }

                    muser.ChangePassword(Parola, passwordTB.Text);
                    Membership.UpdateUser(muser);

                }
                else
                {
                    MyTrace("<--oAutentificare(5)");
                    return;
                }
            }

            Byte[] retCode = GetHash(passwordTB.Text, "gfdgfdrrttrd6786vjbnvbc");
            parolaDB = System.Text.ASCIIEncoding.ASCII.GetString(retCode);


            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration("ERPStudio.exe");
            // Get the connection strings section.

            ConnectionStringsSection csSection = config.ConnectionStrings;
            KeyValueConfigurationCollection configSettings = config.AppSettings.Settings;

            if (configSettings["LastUser"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("LastUser", userTB.Text));
            }
            else {
                configSettings["LastUser"].Value = userTB.Text;
            }
            if (configSettings["LastPassword"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("LastPassword", parolaDB));
            }
            else
            {
                configSettings["LastPassword"].Value = parolaDB;
            }
            if (configSettings["Autentificare"] == null)
            {
                config.AppSettings.Settings.Add(new KeyValueConfigurationElement("Autentificare", retineCB.Checked.ToString()));
            }
            else
            {
                configSettings["Autentificare"].Value = retineCB.Checked.ToString();
            }

            config.Save(ConfigurationSaveMode.Full);   
            Close();

            MyTrace("<--oAutentificare(6)");
        }

        //private Byte[] GetHash(String parola, String salt)
        //{
        //    System.Security.Cryptography.RNGCryptoServiceProvider.Create();
        //    Byte[] NewPasswordBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(parola);
        //    Byte[] saltBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(salt);
        //    Byte[] combinedBytes = new Byte[NewPasswordBytes.Length + saltBytes.Length];
        //    System.Buffer.BlockCopy(NewPasswordBytes, 0, combinedBytes, 0, NewPasswordBytes.Length);
        //    System.Buffer.BlockCopy(saltBytes, 0, combinedBytes, NewPasswordBytes.Length, saltBytes.Length);
        //    System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA1Managed();
        //    Byte[] hash = hashAlgo.ComputeHash(combinedBytes);
        //    for (int i = 0; i < hash.Length; i++)
        //        if (hash[i] == 0)
        //            hash[i] = (Byte)' ';
        //    return hash;
        //}

        /// <summary>
        /// pregateste parola pentru a fi salvata in fisierul de configurare
        /// </summary>
        /// <param name="parola"></param>
        /// <param name="salt"></param>
        /// <returns></returns>
        private Byte[] GetHash(String parola, String salt)
        {

            Byte[] NewPasswordBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(parola);
            Byte[] saltBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(salt);
            Byte[] combinedBytes = new Byte[NewPasswordBytes.Length*2 + saltBytes.Length];
            System.Buffer.BlockCopy(saltBytes, 0, combinedBytes, NewPasswordBytes.Length*2, saltBytes.Length);
            for (int i = 0; i < NewPasswordBytes.Length; i++)
            {
                combinedBytes[2*i] = (byte)(NewPasswordBytes[i] + 2);
                combinedBytes[2*i+1] = (byte)(NewPasswordBytes[i] - 2);
            }
            return combinedBytes;
        }

        private string Decrypt(String parola, String salt)
        {
            if (parola.Length <= salt.Length)
                return String.Empty;
            Byte[] NewPasswordBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(parola);
            Byte[] saltBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(salt);
            Byte[] combinedBytes = new Byte[(parola.Length - salt.Length)/2];
            for (int i = 0; i < combinedBytes.Length; i++)
            {
                combinedBytes[i] = (byte)(NewPasswordBytes[2*i] - 2);
            }
            return System.Text.ASCIIEncoding.ASCII.GetString(combinedBytes);
        }



        override public void InchideFrm(object sender, EventArgs e)
        {
            Application.Exit();
            //this.Close();
        }

        private void LoginAppFrm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(_UserID==Guid.Empty)
                Application.Exit();
        }

    }

}
